package strain.solver;

import java.util.Collection;
import java.util.Comparator;

import strain.domain.CompareWrapper;
import strain.domain.DiscreteDomain;
import strain.expression.Expression;

public class SmallestBranchChooser implements BranchChooser {
    
    private static final Comparator<Expression<?,?>> comp = new Comparator<Expression<?,?>>(){
        public int compare(final Expression<?, ?> e1, final Expression<?, ?> e2) {
            if (e1.isBound() && (e2.isBound())) return 0;
            if (e2.isBound()) return -1;
            if (e1.isBound()) return 1;
            
            boolean e1Discrete = true;
            DiscreteDomain<?> e1d = null;
            try{
                e1d = (DiscreteDomain<?>) e1.getDomain();
            } catch (ClassCastException cce){
                e1Discrete = false;
            }
            boolean e2Discrete = true;
            DiscreteDomain<?> e2d = null;
            try{
                e2d = (DiscreteDomain<?>) e2.getDomain();
            } catch (ClassCastException cce){
                e2Discrete = false;
            }
            // Discrete by size
            if (e1Discrete && !e2Discrete) return -1;
            if (!e1Discrete && e2Discrete) return 1;
            if (e1Discrete && e2Discrete) return (e1d.size() - e2d.size());
            // Continuous by length?
            return 0;
        }
    };
    
    private static final CompareWrapper<Expression<?,?>> cw = new CompareWrapper<Expression<?,?>>(comp);
    
    public Expression<?,?> chooseBranchExpression(final Collection<Expression<?,?>> expressions) {
        Expression<?,?> result = null;
        for(Expression<?,?> e: expressions){
            result = cw.min(result, e);
        }
        return result;
    }

}
